package com.uinnova.product.eam.web.diagram.bean.impt;

import com.binary.core.exception.MessageException;
import com.binary.core.i18n.LanguageResolver;
import com.binary.core.io.Resource;
import com.binary.core.io.support.ByteArrayResource;
import com.binary.core.util.BinaryUtils;
import com.binary.framework.web.LocalSpace;
import com.binary.tools.excel.ExcelUtils;
import com.binary.tools.excel.ExcelUtils.SheetInfo;
import org.apache.commons.io.IOUtils;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

public class ImportMessageUtil {
	
	private static final String NEW_LINE="\r\n";
	private static final String D_NEW_LINE="\r\n\r\n";
	
	public static final Integer CI_DATA_IMPORT_TYPE = 1;
	
	public static final String CI_CLASS_IMPORT_TYPE = "ciClassImport";
	
	public static final Integer RLT_DATA_IMPORT_TYPE = 2;
	
	public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	public static final Map<Integer,String> errorTypeMsg = new HashMap<Integer, String>();

	
	static {
		ImportErrorMsgLabel label = new ImportErrorMsgLabel(true);
		errorTypeMsg.put(0, label.getFailed());
		errorTypeMsg.put(1, label.getSuccessful());
		errorTypeMsg.put(2, label.getRequiredFieldMissing());
		errorTypeMsg.put(3, label.getLongLength());
		errorTypeMsg.put(4, label.getTypeError());
		errorTypeMsg.put(5, label.getRequiredFieldMissing());
		errorTypeMsg.put(6, label.getPrimaryKeyRepeat());
		errorTypeMsg.put(7, label.getDuplicateValue());
		errorTypeMsg.put(8, label.getAlreadyExists());
		errorTypeMsg.put(9, label.getDoesNotExists());
		errorTypeMsg.put(10, label.getCiCodeRepeat());
	}

	public static void init() {
		ImportErrorMsgLabel label = new ImportErrorMsgLabel(true);
		errorTypeMsg.clear();
		errorTypeMsg.put(0, label.getFailed());
		errorTypeMsg.put(1, label.getSuccessful());
		errorTypeMsg.put(2, label.getRequiredFieldMissing());
		errorTypeMsg.put(3, label.getLongLength());
		errorTypeMsg.put(4, label.getTypeError());
		errorTypeMsg.put(5, label.getRequiredFieldMissing());
		errorTypeMsg.put(6, label.getPrimaryKeyRepeat());
		errorTypeMsg.put(7, label.getDuplicateValue());
		errorTypeMsg.put(8, label.getAlreadyExists());
		errorTypeMsg.put(9, label.getDoesNotExists());
		errorTypeMsg.put(10, label.getCiCodeRepeat());

	}

	public static String getImportType(Integer type) {
		if (type == CI_DATA_IMPORT_TYPE) {
			return new ImportErrorMsgLabel(true).getCiDataImportType();
		} else if(type == RLT_DATA_IMPORT_TYPE) {
			return new ImportErrorMsgLabel(true).getRltDataImportType();
		}
		else {
			return null;
		}
	}

	
	
	public static String importMsg2String(ImportMessage message){
		if(message == null) return "";
		
		return importSheetMsg2String(message.getResultMessage());
	}

	public static String importSheetMsg2String(List<ImportSheetMessage> sheetMsgs){
		if(BinaryUtils.isEmpty(sheetMsgs)) return "";

		StringBuffer msgBuf = new StringBuffer(1000);
		for (ImportSheetMessage sheetMessage : sheetMsgs) {
			String sheetMsg = sheetMsg2String(sheetMessage);
			msgBuf.append(sheetMsg);
			msgBuf.append(NEW_LINE);
		}
		return msgBuf.toString();
	}	
	
	
	private static String sheetMsg2String(ImportSheetMessage sheetMessage){
		StringBuffer msgBuf = new StringBuffer(1000);
		title(sheetMessage, msgBuf);
		
	
		List<ImportRowMessage> rowMessages = sheetMessage.getRowMessages();
		for (ImportRowMessage rowMessage : rowMessages) {
			String rowMsg2String = rowMsg2String(rowMessage);
			msgBuf.append(rowMsg2String).append(NEW_LINE);
		}
		return msgBuf.toString();
	}

	private static void title(ImportSheetMessage sheetMessage, StringBuffer msgBuf) {

		String className = sheetMessage.getClassName();
		Integer failNum = sheetMessage.getFailNum();
		Integer totalNum = sheetMessage.getTotalNum();
		Integer successNum = sheetMessage.getSuccessNum();
		Integer ignoreNum = sheetMessage.getIgnoreNum();

		Integer insertNum = sheetMessage.getInsertNum();
		Integer updateNum = sheetMessage.getUpdateNum();

		Map<String, String> params = new HashMap<>();
		if (className != null) params.put("className", sheetMessage.getClassName());
		if(failNum != null) params.put("failNum", failNum.toString());
		if(totalNum != null) params.put("totalNum", totalNum.toString());
		if(successNum != null) params.put("successNum", successNum.toString());
		if(ignoreNum != null) params.put("ignoreNum", ignoreNum.toString());
		if(insertNum != null) params.put("insertNum", insertNum.toString());
		if(updateNum != null) params.put("updateNum", updateNum.toString());
		if(insertNum != null && updateNum != null && ignoreNum != null) params.put("processNum", Integer.toString(insertNum + updateNum + ignoreNum));
		
		if(sheetMessage.getSuccess() == null || sheetMessage.getSuccess() == 0){
			msgBuf.append(LanguageResolver.trans("BS_IMPORT_MSG_CLASS_NOT_EXIST", params)).append(D_NEW_LINE);
		}else {
			if (sheetMessage.getInsertNum() == null) {
				msgBuf.append(LanguageResolver.trans("BS_IMPORT_MSG_CLASS", params)).append(NEW_LINE);
				msgBuf.append(LanguageResolver.trans("BS_IMPORT_MSG_NUM", params)).append(", ")
						.append(LanguageResolver.trans("BS_IMPORT_MSG_SUCCESS", params)).append(", ")
						.append(LanguageResolver.trans("BS_IMPORT_MSG_NUM", params))
						.append(D_NEW_LINE);
			} else {
				msgBuf.append(LanguageResolver.trans("BS_IMPORT_MSG_CLASS", params)).append(NEW_LINE);
				msgBuf.append(LanguageResolver.trans("BS_IMPORT_MSG_PROCESS", params)).append(", ")
						.append(LanguageResolver.trans("BS_IMPORT_MSG_ADD", params)).append(", ")
						.append(LanguageResolver.trans("BS_IMPORT_MSG_IGNORE", params)).append(", ")
						.append(LanguageResolver.trans("BS_IMPORT_MSG_UPDATE", params))
						.append(D_NEW_LINE);
			}
		}
	}



	
	public static String getTitle(ImportSheetMessage sheetMessage) { 
		StringBuffer msgBuf = new StringBuffer(1000);
		title(sheetMessage, msgBuf);
		return msgBuf.toString();
	}
	
	private static String rowMsg2String(ImportRowMessage rowMessage){
		if(rowMessage == null) return "";
		List<ImportCellMessage> messageItems = rowMessage.getMessageItems();
		if(BinaryUtils.isEmpty(messageItems)) return "";
		
		Integer rowNum = rowMessage.getRowNum();
		Map<String, String> param = new HashMap<>();
		param.put("rowNum", rowNum.toString());
		StringBuffer msgBuf = new StringBuffer(1000);
		msgBuf.append(LanguageResolver.trans("BS_IMPORT_MSG_LINE", param)).append("\t\t");
		for (ImportCellMessage cellMessage : messageItems) {
			String str = cellMsg2String(cellMessage);
			if(!BinaryUtils.isEmpty(str)){
				msgBuf.append(str).append("\t");
			}
		}
		return msgBuf.toString();
	}
	
	private static String cellMsg2String(ImportCellMessage cellMessage){
		if(cellMessage == null) return "";
		Integer errorType = cellMessage.getErrorType();
		String fieldName = cellMessage.getFieldName();
		ImportMessageUtil.init();
/*		if (SystemUtil.getLoginUser().getLanguage().equals(Language.EN))
			return "Attribute: " + fieldName + ", " + errorTypeMsg.get(errorType);
		else*/
			return "属性: "+ fieldName + ", " + errorTypeMsg.get(errorType);
	}
	
	/**
	 * 将导入信息转换成一行一行的Map格式
	 * @return
	 */
	public static Map<Integer, String> toRowStringMap(ImportSheetMessage sheetMessage) {
		Map<Integer, String> map = new HashMap<Integer, String>();
		List<ImportRowMessage> rowMessages = sheetMessage.getRowMessages();
		for (ImportRowMessage rowMessage : rowMessages) {
			if(rowMessage == null) continue;
			List<ImportCellMessage> messageItems = rowMessage.getMessageItems();
			if(BinaryUtils.isEmpty(messageItems)) continue;
			
			Integer rowNum = rowMessage.getRowNum();
			StringBuffer msgBuf = new StringBuffer(1000);
			for (ImportCellMessage cellMessage : messageItems) {
				String str = cellMsg2String(cellMessage);
				if(!BinaryUtils.isEmpty(str)){
					msgBuf.append(str).append("\t");
				}
			}
			int length = msgBuf.length();
			if (length>0) {
				msgBuf.deleteCharAt(length - 1);
			}
			map.put(rowNum, msgBuf.toString().trim());
		}
		return map;
	}
	public static String row2String(ImportRowMessage rowMessage) {
		if(rowMessage == null) return "";
		List<ImportCellMessage> messageItems = rowMessage.getMessageItems();
		if(BinaryUtils.isEmpty(messageItems)) return "";
		
//		Integer rowNum = rowMessage.getRowNum();
		StringBuffer msgBuf = new StringBuffer(1000);
//		msgBuf.append("第 ").append(rowNum).append(" 行 ");
		for (ImportCellMessage cellMessage : messageItems) {
			String str = cellMsg2String(cellMessage);
			if(!BinaryUtils.isEmpty(str)){
				msgBuf.append(str).append("|");
			}
		}
		int length = msgBuf.length();
		if (length>0) {
			msgBuf.deleteCharAt(length - 1);
		}
		return msgBuf.toString();
	}
	
	/**
	 * 将导入的信息保存到文件中
	 * @param msgType {@link ImportMessageUtil#CI_DATA_IMPORT_TYPE } | {@link ImportMessageUtil#CI_CLASS_IMPORT_TYPE}
	 * @param user 当前操作的用户
	 * @param message 操作信息
	 * @return 保存的文件名字
	 */
	public static String saveImportMsg(String msgType, String user, ImportMessage message) {
		List<ImportSheetMessage> sheetMsgs = null;
		
		if(message != null) sheetMsgs = message.getResultMessage();
		
		return saveImportSheetMsgs(msgType, user, sheetMsgs);
	}
	/**
	 * 将导入的信息保存到文件中
	 * @param msgType {@link ImportMessageUtil#CI_DATA_IMPORT_TYPE} | {@link ImportMessageUtil#CI_CLASS_IMPORT_TYPE}
	 * @param user 当前操作的用户
	 * @param sheetMsgs 操作信息
	 * @return 保存的文件名字
	 */
	public static String saveImportSheetMsgs(String msgType, String user, List<ImportSheetMessage> sheetMsgs) {
		Date date = new Date();
		
		String fileName = buildFileName(msgType, date);
		String opInfo = buildOpInfo(user, date);
		String msgInfo = importSheetMsg2String(sheetMsgs);
		
		StringBuffer cntBuf = new StringBuffer(1000);
		cntBuf.append(opInfo);
		cntBuf.append(msgInfo);
		
		saveFile(msgType, fileName, cntBuf.toString());
		
		return fileName;
	}
	/**
	 * 将导入的信息保存到文件中
	 * @param msgType {@link ImportMessageUtil#CI_DATA_IMPORT_TYPE} | {@link ImportMessageUtil#CI_CLASS_IMPORT_TYPE}
	 * @param user 当前操作的用户
	 * @param sheetMsg 操作信息
	 * @return 保存的文件名字
	 */
	public static String saveImportSheetMsg(String msgType, String user, ImportSheetMessage sheetMsg) {
		Date date = new Date();
		
		List<ImportSheetMessage> sheetMsgs =new ArrayList<ImportSheetMessage>();
		if(sheetMsg != null) {
			sheetMsgs.add(sheetMsg);
		}
		
		String fileName = buildFileName(msgType, date);
		String opInfo = buildOpInfo(user, date);
		String msgInfo = importSheetMsg2String(sheetMsgs);
		
		StringBuffer cntBuf = new StringBuffer(1000);
		cntBuf.append(opInfo);
		cntBuf.append(msgInfo);
		
		saveFile(msgType, fileName, cntBuf.toString());
		
		return fileName;
	}
	/**
	 * 将一键批量导入的信息保存到文件中
	 * @param msgType
	 * @param userCode
	 * @param sheetMsgs
	 * @return
	 */
	public static String saveImportSheetMsg(String msgType, String userCode, ArrayList<ImportSheetMessage> sheetMsgs) {
		Date date = new Date();
		
		String fileName = buildFileName(msgType, date);
		String opInfo = buildOpInfo(userCode, date);
		String msgInfo = importSheetMsg2String(sheetMsgs);
		
		StringBuffer cntBuf = new StringBuffer(1000);
		cntBuf.append(opInfo);
		cntBuf.append(msgInfo);
		
		saveFile(msgType, fileName, cntBuf.toString());
		
		return fileName;
	}
	
	/**
	 * 将导入忽略的信息保存到Excel中
	 * @param msgType
	 * @param userCode
	 * @param sheetMsgs
	 * @return
	 */
	public static String saveIgnoreMsgExcel(String msgType, String userCode, List<ImportSheetMessage> sheetMsgs) {
		if (BinaryUtils.isEmpty(sheetMsgs)) return null;
		Date date = new Date();
		
		String fileName = buildExcelName(msgType, date);
		
		List<SheetInfo> sheets=null;
		if (!BinaryUtils.isEmpty(sheetMsgs)) {
			sheets  = new ArrayList<SheetInfo>();
			for (ImportSheetMessage sheetMsg : sheetMsgs) {
				SheetInfo sheetInfo = sheetMsg.getSheetInfo();
				if (!BinaryUtils.isEmpty(sheetInfo)) {
					sheets.add(sheetInfo);
				}
			} 
		}
		if (BinaryUtils.isEmpty(sheets)) return null;
		
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		ExcelUtils.export(sheets, os);
		Resource resource = new ByteArrayResource(os.toByteArray(), fileName);
		InputStream inputStream = resource.getInputStream();
		saveExcel(msgType,fileName, inputStream);

		return fileName;
	}
	
	
	
	/**
	 * 通过导入类型和文件名获取文件内容
	 * @param msgType {@link ImportMessageUtil#CI_DATA_IMPORT_TYPE} | {@link ImportMessageUtil#CI_CLASS_IMPORT_TYPE}
	 * @param fileName
	 * @return
	 */
	public static String getImportMsg(String msgType,String fileName) {
		File space = LocalSpace.getSpace(msgType);
		File file = new File(space, fileName);
		
		if(!file.exists()) return "";
		
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(file);
			return IOUtils.toString(fis, "UTF-8");
		} catch (Exception e) {
			return "";
		}finally{
			if (fis != null) {
				try {
					fis.close();
				} catch (Exception e2) {
				}
			}
		}
	}
	
	private static String buildFileName(String msgType, Date date) {
		if(date == null) {
			date = new Date();
		}
		StringBuffer fileNameBuf = new StringBuffer(1000);
		fileNameBuf.append(msgType).append(BinaryUtils.getNumberDateTime(date)).append(".txt");
		return fileNameBuf.toString();
	}
	
	private static String buildExcelName(String msgType, Date date) {
		if(date == null) {
			date = new Date();
		}
		StringBuffer fileNameBuf = new StringBuffer(1000);
		fileNameBuf.append(msgType).append(BinaryUtils.getNumberDateTime(date)).append(".xls");
		return fileNameBuf.toString();
	}
	
	private static String buildOpInfo(String user, Date date) {
		if(date == null) {
			date = new Date();
		}
		Map<String, String> params = new HashMap<>();
		params.put("user", user);
		params.put("date", DATE_FORMAT.format(date));
		StringBuffer opBuf = new StringBuffer(1000);
		opBuf.append(LanguageResolver.trans("BS_IMPORT_MSG_USER", params)).append(", ")
				.append(LanguageResolver.trans("BS_IMPORT_MSG_DATE", params)).append(D_NEW_LINE);
		return opBuf.toString();
	}
	
	private static void saveFile(String msgType, String fileName, String content) {
		LocalSpace.getRoot();
		File space = LocalSpace.getSpace(msgType);
		if(!space.exists()) space.mkdirs();
		
		File file = new File(space, fileName);

		FileOutputStream output = null;
		try {
//			file.createNewFile();
			output = new FileOutputStream(file);
			IOUtils.write(content, output,"UTF-8");
		} catch (IOException e) {
			throw MessageException.i18n("BS_MNAME_SAVE_FAIL");
		}finally {
			if(output != null) {
				try {
					output.close();
				} catch (IOException e) {
				}
			}
		}
	}
	
	public static List<List<String>> getErrMessagesFields(ImportSheetMessage importSheetMessage) {
		if (BinaryUtils.isEmpty(importSheetMessage)) return Collections.emptyList();
		
		List<ImportRowMessage> rowMessages = importSheetMessage.getRowMessages();
		List<List<String>> rowAndCellMessages = new ArrayList<List<String>>(rowMessages.size());
		for (ImportRowMessage row : rowMessages) {
			List<ImportCellMessage> cells = row.getMessageItems();
			List<String> errAttrNames = new ArrayList<String>(rowMessages.size());
			for (ImportCellMessage cell : cells) {
				String fieldName = cell.getFieldName();
				errAttrNames.add(fieldName);
			}
			rowAndCellMessages.add(errAttrNames);
		}
		return rowAndCellMessages;
	}
	
	private static File saveExcel(String msgType, String fileName, InputStream is) {
		LocalSpace.getRoot();
		File space = LocalSpace.getSpace(msgType);
		if(!space.exists()) space.mkdirs();
		
		File file = new File(space, fileName);
		FileOutputStream output = null;
		try {
//			file.createNewFile();
			output = new FileOutputStream(file);
			IOUtils.copy(is, output);
		} catch (IOException e) {
			throw MessageException.i18n("BS_MNAME_SAVE_FAIL");
		}finally {
			if(output != null) {
				try {
					output.close();
				} catch (IOException e) {
				}
			}
		}
		return file;
	
	}
	

	public static byte[] getImportIgroneExcel(String msgType,String fileName) {
		File space = LocalSpace.getSpace(msgType);
		File file = new File(space, fileName);
		
		if(!file.exists()) return new byte[0];
		
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(file);
			return IOUtils.toByteArray(fis);
		} catch (Exception e) {
			return new byte[0];
		}finally{
			if (fis != null) {
				try {
					fis.close();
				} catch (Exception e2) {
				}
			}
		}
	}
	
}
